#include "app_config.h"
#include <pin_name.h>
#include <aos/aos.h>
#include <yoc/button.h>
#include <yoc/lpm.h>
#include "app_main.h"

#define TAG "app_key"

typedef struct _evt_data{
    int event_id;
    char name[MAX_BUTTON_NAME];
} evt_data_t;
#define MESSAGE_NUM 10
static uint8_t s_q_buffer[sizeof(evt_data_t) * MESSAGE_NUM];
static aos_queue_t s_queue;
extern int wifi_prov_method;

static void button_evt(button_evt_id_t event_id, char *name, void *priv)
{
    LOGE(TAG, "evt[%d] key[%s]", event_id, name);
    evt_data_t data;
    data.event_id = event_id;
    strlcpy(data.name, name, MAX_BUTTON_NAME);
    int ret = aos_queue_send(&s_queue, &data, sizeof(evt_data_t));
    if (ret < 0) {
        LOGE(TAG, "queue send failed");
    }
}

static void bc_evt(button_evt_id_t event_id, char *name, void *priv)
{
    LOGE(TAG, "bc evt[%s], id %d", name, event_id);
    evt_data_t data;
    data.event_id = event_id;
    strlcpy(data.name, name, MAX_BUTTON_NAME);
    int ret = aos_queue_send(&s_queue, &data, sizeof(evt_data_t));
    if (ret < 0) {
        LOGE(TAG, "queue send failed");
    }
}
// FIXME: BUTTON配置和上报的事件ID需要统一
const static button_config_t button_table[] = {
#ifdef APP_KEY_MUTE
    {APP_KEY_MUTE,    (PRESS_UP_FLAG | PRESS_LONG_DOWN_FLAG), button_evt, NULL, BUTTON_TYPE_GPIO,  "mute"},
#endif
#ifdef APP_KEY_VOL_INC
    {APP_KEY_VOL_INC, (PRESS_UP_FLAG | PRESS_LONG_DOWN_FLAG), button_evt, NULL, BUTTON_TYPE_GPIO,  "inc"},
#endif
#ifdef APP_KEY_VOL_DEC
    {APP_KEY_VOL_DEC, (PRESS_UP_FLAG | PRESS_LONG_DOWN_FLAG), button_evt, NULL, BUTTON_TYPE_GPIO,  "dec"},
#endif
#ifdef APP_KEY_STANDBY
    {APP_KEY_STANDBY, (PRESS_UP_FLAG | PRESS_LONG_DOWN_FLAG), button_evt, NULL, BUTTON_TYPE_GPIO,  "standby"},
#endif
    {0, 0, NULL, NULL},
};

const static button_combinations_t bc_table[] = {
    {
        .pin_name[0] = "mute",
        .pin_name[1] = "inc",
        .evt_flag = PRESS_LONG_DOWN_FLAG,
        .pin_sum = 2,
        .tmout = 500,
        .cb = bc_evt,
        .priv = NULL,
        .name = "mute&inc_long"
    },
    {
        .pin_name[0] = "mute",
        .pin_name[1] = "dec",
        .evt_flag = PRESS_LONG_DOWN_FLAG,
        .pin_sum = 2,
        .tmout = 500,
        .cb = bc_evt,
        .priv = NULL,
        .name = "mute&dec_long"
    },
    {
        .pin_name[0] = "mute",
        .pin_name[1] = "inc",
        .evt_flag = PRESS_UP_FLAG,
        .pin_sum = 2,
        .tmout = 200,
        .cb = bc_evt,
        .priv = NULL,
        .name = "mute&inc_short"
    },
    {
        .pin_name[0] = "mute",
        .pin_name[1] = "dec",
        .evt_flag = PRESS_UP_FLAG,
        .pin_sum = 2,
        .tmout = 200,
        .cb = bc_evt,
        .priv = NULL,
        .name = "mute&dec_short"
    },
    {
        .pin_sum = 0,
        .cb = NULL,
    },
};

static void button_task_thread(void *arg)
{
    evt_data_t data;
    unsigned int len;

    while (1) {
        aos_queue_recv(&s_queue, AOS_WAIT_FOREVER, &data, &len);

        if (strcmp(data.name, "mute") == 0) {
            if (data.event_id == BUTTON_PRESS_LONG_DOWN) {
                wifi_prov_method = WIFI_PROVISION_SOFTAP;
                aos_kv_setint("wprov_method", wifi_prov_method);
                app_sys_set_boot_reason(BOOT_REASON_WIFI_CONFIG);
                aos_reboot();
            } else if (data.event_id == BUTTON_PRESS_UP) {
                mplayer_pause(SOURCE_LOCAL);
            }
        } else if (strcmp(data.name, "inc") == 0) {
            mplayer_vol_up(SOURCE_LOCAL, 10);
        } else if (strcmp(data.name, "dec") == 0) {
            mplayer_vol_down(SOURCE_LOCAL, 10);
        } else if (strcmp(data.name, "standby") == 0) {
            mplayer_stop(SOURCE_LOCAL, MEDIA_ALL);
            pm_config_policy(LPM_POLICY_DEEP_SLEEP);
            pm_agree_halt(0);
        } else if (data.event_id == BUTTON_COMBINATION) {
            if (strcmp(data.name, "mute&inc_long") == 0) {
                LOGE(TAG, "enter smartconfig provision");
                wifi_prov_method = WIFI_PROVISION_SL_SMARTCONFIG;
            } else if (strcmp(data.name, "mute&dec_long") == 0) {
                LOGE(TAG, "enter devap provision");
                wifi_prov_method = WIFI_PROVISION_SL_DEV_AP;
            } else {
                continue;
            }

            aos_kv_setint("wprov_method", wifi_prov_method);
            app_sys_set_boot_reason(BOOT_REASON_WIFI_CONFIG);
            aos_reboot();
        }
    }
}

static void button_task(void)
{
    aos_task_t task;

    int ret = aos_queue_new(&s_queue, s_q_buffer, MESSAGE_NUM * sizeof(evt_data_t), sizeof(evt_data_t));
    aos_check(!ret, EIO);
    aos_task_new_ext(&task, "b-press", button_task_thread, NULL, 4096, AOS_DEFAULT_APP_PRI + 4);
}

void app_button_init(void)
{
    /* 按键初始化 */
    button_task();
    button_srv_init();
    button_init(button_table);
    button_param_t pb;
    button_param_cur("mute", &pb);
    pb.ld_tmout = 2000;
    button_param_set("mute", &pb);
    button_param_set("inc", &pb);
    button_param_set("dec", &pb);
    button_combination_init(bc_table);
}
